﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using System.Web.Security;
using System.Security.Principal;

namespace DocManagerControls.CLASSI
{
   public  class ActiveDir
    {
       

       public ActiveDir()
       {
       }



       public void creaIdentity()
       {
          //Create an Identity.
         //GenericIdentity id = new GenericIdentity(authTicket.Name, "LdapAuthentication");
	
          //This principal flows throughout the request.
          //GenericPrincipal principal = new GenericPrincipal(id, groups);
       
       }//fM


      

       public static DirectoryEntry GetDirectoryEntry(string pDominio,AuthenticationTypes pAutType)
       {
           DirectoryEntry de = new DirectoryEntry();
           de.Path = string.Format("LDAP://OU=Domain,DC={0},DC=it", pDominio);
           de.AuthenticationType = pAutType;
           return de;
       }//fM

       public static bool UserExists(string username, string pDominio)
       {
           DirectoryEntry de = GetDirectoryEntry(pDominio,AuthenticationTypes.Secure);
           DirectorySearcher deSearch = new DirectorySearcher();
           deSearch.SearchRoot = de;
           deSearch.Filter = "(&(objectClass=user) (cn=" + username + "))";
           SearchResultCollection results = deSearch.FindAll();
           return results.Count > 0;


       }//fM

       public static String FindName(String userAccount, string pDominio)
       {
           DirectoryEntry entry = GetDirectoryEntry(pDominio,AuthenticationTypes.None);
           String account = userAccount.Replace(@"Domain\", "");
           try
           {
               DirectorySearcher search = new DirectorySearcher(entry);
               search.Filter = "(SAMAccountName=" + account + ")";
               search.PropertiesToLoad.Add("displayName");
               SearchResult result = search.FindOne();
               if (result != null)
               {
                   return result.Properties["displayname"][0].ToString();
               }
               else
               {
                   return "Unknown User";
               }
           }
           catch (Exception ex)
           {
               string debug = ex.Message;

               return "";
           }
       }//fM


       public static bool ModifyUser( string pDominio,string userDisplayName, string username, string password)
        {
            using (DirectoryEntry de = GetDirectoryEntry(pDominio,AuthenticationTypes.None))
            {
                de.Username = username;
                de.Password = password;
                DirectorySearcher ds = new DirectorySearcher(de);
                ds.Filter = ("(&(objectclass=user)(objectcategory=person)(displayname=" + userDisplayName + "))");
                ds.SearchScope = SearchScope.Subtree;
                SearchResult results = ds.FindOne();
                if (results != null)
                {
                    try
                    {
                        DirectoryEntry updateEntry = results.GetDirectoryEntry();
                        updateEntry.Properties["department"].Value = "555";
                        updateEntry.CommitChanges();
                        updateEntry.Close();
                        return true;
                    }
                    catch (Exception ex)
                    {
                        var err = ex.ToString();
                        return false;
                    }
                }
            }
            return false;
        }//fM




       #region LDAP

        private String _pathLDAP;
        private String _filterAttribute;

       public string LDAPPathFull { get{ return _pathLDAP;} set{_pathLDAP = value;} }


       public IList<string> GetGroups()
     {
       DirectorySearcher search = new DirectorySearcher(_pathLDAP);
       search.Filter = "(cn=" + _filterAttribute + ")";
       search.PropertiesToLoad.Add("memberOf");
       IList<string> gruppiList = new List<string>();

       try
       {
         SearchResult result = search.FindOne();

	     int propertyCount = result.Properties["memberOf"].Count;

   	     String dn;
	     int equalsIndex, commaIndex;
				
	     for(int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++)
	     {
	           dn = (String)result.Properties["memberOf"][propertyCounter];

    	       equalsIndex = dn.IndexOf("=", 1);
	           commaIndex = dn.IndexOf(",", 1);
	       
               if(-1 == equalsIndex) return null;


               gruppiList.Add(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
	          

    	     }
           }
           catch(Exception ex)
           {
             throw new Exception("Errore active dir. nel prelievo gruppi utente " + ex.Message);
           }

       return gruppiList;

         }//fM
  

       public bool IsAuthenticated(String domain, String username, String pwd)
        {
              String domainAndUsername = domain + @"\" + username;
              DirectoryEntry entry = new DirectoryEntry(_pathLDAP, domainAndUsername, pwd);
			
              try
              {	//Bind to the native AdsObject to force authentication.			
                 Object obj = entry.NativeObject;

	        DirectorySearcher search = new DirectorySearcher(entry);

	        search.Filter = "(SAMAccountName=" + username + ")";
	        search.PropertiesToLoad.Add("cn");
	        SearchResult result = search.FindOne();

	        if(null == result)
	        {
  	          return false;
	        }

	        //Update the new path to the user in the directory.
            _pathLDAP = result.Path;
	        _filterAttribute = (String)result.Properties["cn"][0];
              }
              catch (Exception ex)
              {
                throw new Exception("Error authenticating user. " + ex.Message);
              }

	        return true;
        }//fM


       public IList<string> GetUsers(string pLocalUsername,string pLocalPassword)
        {
          IList<string> users = new List<string>(10);

          // percorso AD, username e password per interrogare
          string path = _pathLDAP ; // ""_blank" href="LDAP://server2003/DC=bochicchio'>LDAP://server2003/DC=bochicchio,DC=local";
          string localUsername = pLocalUsername;
          string localPassword = pLocalPassword;

          // effettuo una ricerca in ActiveDirectory
          DirectorySearcher search = new DirectorySearcher(new DirectoryEntry(path, localUsername, localPassword));
          search.Filter = "(&(objectclass=user)(objectCategory=person))"; // solo persone
  
          // proprietà richieste
          search.PropertiesToLoad.Add("samaccountname");

          search.CacheResults = true;
          search.SizeLimit = 1000; // massimo 1000 utenti

          // cerco gli utenti
          SearchResultCollection results = search.FindAll();
          foreach(SearchResult result in results) 
          {
            // aggiugno lo username alla collezione
            users.Add(result.Properties["samaccountname"][0].ToString());
          }
          search.Dispose();

          // restituisco un array di stringhe
          return users;
        }//fM


       #endregion

    }//fC
}
